From: Andrew Cooper Date: Wed, 23 Jul 2014 16:07:11 +0000 (+0200) Subject: x86/mem_event: validate the response vcpu_id before acting on it X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~4622 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22?a=commitdiff_plain;h=ee75480b3c8856db9ef1aa45418f35ec0d78989d;p=xen.git x86/mem_event: validate the response vcpu_id before acting on it Signed-off-by: Andrew Cooper Reviewed-by: Tim Deegan Reviewed-by: Andres Lagar-Cavilla Tested-by: Razvan Cojocaru --- diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c index 7293f319cb..ec99266280 100644 --- a/xen/arch/x86/mm/mem_sharing.c +++ b/xen/arch/x86/mm/mem_sharing.c @@ -596,11 +596,20 @@ int mem_sharing_sharing_resume(struct domain *d) /* Get all requests off the ring */ while ( mem_event_get_response(d, &d->mem_event->share, &rsp) ) { + struct vcpu *v; + if ( rsp.flags & MEM_EVENT_FLAG_DUMMY ) continue; + + /* Validate the vcpu_id in the response. */ + if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] ) + continue; + + v = d->vcpu[rsp.vcpu_id]; + /* Unpause domain/vcpu */ if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) - vcpu_unpause(d->vcpu[rsp.vcpu_id]); + vcpu_unpause(v); } return 0; diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c index 642ec28889..f213a392c1 100644 --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -1290,8 +1290,17 @@ void p2m_mem_paging_resume(struct domain *d) /* Pull all responses off the ring */ while( mem_event_get_response(d, &d->mem_event->paging, &rsp) ) { + struct vcpu *v; + if ( rsp.flags & MEM_EVENT_FLAG_DUMMY ) continue; + + /* Validate the vcpu_id in the response. */ + if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] ) + continue; + + v = d->vcpu[rsp.vcpu_id]; + /* Fix p2m entry if the page was not dropped */ if ( !(rsp.flags & MEM_EVENT_FLAG_DROP_PAGE) ) { @@ -1310,7 +1319,7 @@ void p2m_mem_paging_resume(struct domain *d) } /* Unpause domain */ if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) - vcpu_unpause(d->vcpu[rsp.vcpu_id]); + vcpu_unpause(v); } } @@ -1418,11 +1427,20 @@ void p2m_mem_access_resume(struct domain *d) /* Pull all responses off the ring */ while( mem_event_get_response(d, &d->mem_event->access, &rsp) ) { + struct vcpu *v; + if ( rsp.flags & MEM_EVENT_FLAG_DUMMY ) continue; + + /* Validate the vcpu_id in the response. */ + if ( (rsp.vcpu_id >= d->max_vcpus) || !d->vcpu[rsp.vcpu_id] ) + continue; + + v = d->vcpu[rsp.vcpu_id]; + /* Unpause domain */ if ( rsp.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) - vcpu_unpause(d->vcpu[rsp.vcpu_id]); + vcpu_unpause(v); } }